﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using KWIC;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;

namespace Hestia_Cyberminer
{
    /// <summary>
    /// This is the class for the Cyberminer.aspx Page(Code Behind)
    /// Note: The index class index was intially a part of the index.aspx but the file was renamed and hence the 
    /// difference in the name between the class and aspx page. 
    /// </summary>
    /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:40 AM
    public partial class index : System.Web.UI.Page
    {
        /// <summary>
        /// The ANETCSSRS list of type string stands for Alphabetized Noise Eliminated Trimmed Circular
        /// Shift Sentences without Removed Sentences.
        /// </summary>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:40 AM
        List<string> ANETCSSRS = new List<string>();
        
        protected void Page_Load(object sender, EventArgs e)
        {
            

        }

        /// <summary>
        /// Handles the Click event of the btnSearch control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:40 AM
        protected void btnSearch_Click(object sender, EventArgs e)
        {
            /*resets all the labels(discussed below)
             */
            resetLabelsAndLists();
            /*processSentences responsible for create the Alphabetized Noise Eliminated Trimmed Circular 
             * Shift Sentences without Removed Sentences and stores it in the ANETCSSRS object.
             */
            ANETCSSRS = processSentences();
            /*method to search the database for the sentences in ANETCSSRS.
             */
            searchDB(ANETCSSRS);
            /*Reset the DataPagers PageIndex property to 1 as a new search is being performed
             */
            DataPager.SetPageProperties( 0, DataPager.MaximumRows, true);
            /*Bind the data to the DataPager.
             */
            DataPager.DataBind();
        }

        /// <summary>
        /// Searches the DataBase.
        /// </summary>
        /// <param name="ANECS">The ANECS.</param>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:42 AM
        private void searchDB(List<string> ANECS)
        {
            /* Gets the Sql Connection String stord in the web.config file under the appSettings Tab.
             * Gives us the ability keep the database configurations outside the Web Application. Helpful when 
             * migrating a database.
             */
            string connectionString = ConfigurationManager.AppSettings["SQLSERVER_CONNECTION_STRING"];
            /* Create a myCommand Object of type SqlCommand.
             */
            SqlCommand myCommand = new SqlCommand();
            /* Create a dataTable Object of type DataTable.
             */
            DataTable dataTable = new DataTable();
            /* Create a myConnection Object of type SqlConnection.
             */
            SqlConnection myConnection = new SqlConnection(connectionString);
            /* generateAndGetQuery method will create the query based on the choices
             * such as case-sensitive, AND, OR, NOT keyword search.
             */
            string query = generateAndGetQuery(ANECS);
            /* Save the query generated into myCommand Object's CommandText Property
             */
            myCommand.CommandText = query;
            /* Save the Sql Connection String into myCommand Object's Connection Property 
             */
            myCommand.Connection = myConnection;
            /* Open the database connection
             */
            try
            {
                myConnection.Open();
                /* Create a Sql Data Adapter da that will contain the myCommand Objects Details.
                 */
                SqlDataAdapter ad = new SqlDataAdapter(myCommand);
                /* Fill the datatable upon query execution.
                 */
                ad.Fill(dataTable);
                /* Store the datatable contents onto the list view lvSearchResults created on the 
                 * Cyberminer.apsx page.
                 */
                lvSearchResults.DataSource = dataTable;
                /* Bind the data to the list view.
                 */
                lvSearchResults.DataBind();
                /* Execute the Sql query.
                 */
                myCommand.ExecuteNonQuery();
                /* Close the Database connection.
                 */
                myCommand.Connection.Close();
                /* Make the listview visible.
                 */
            }
            catch (Exception e) { 
            lblDBError.Text = "Database Search Failed";
            }
            lvSearchResults.Visible = true;
            /* Make the Label lblSRText visible.
             */
            lblSRText.Visible = true;
        }

        /// <summary>
        /// Generates and gets query.
        /// </summary>
        /// <param name="ANECS">The ANECS.</param>
        /// <returns></returns>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:48 AM
        private string generateAndGetQuery(List<string> ANECS)
        {
            /* Intial part of the sql statement 
             */
            string query = "SELECT [url_descriptor], [url_hyplerlink], [date_modified]" +
                                   " FROM [url_info] WHERE (";
            /* The end part of the query if AND or OR is selected in the radio button list rbAndOrNot 
             */
            string endQueryString = " %') ORDER BY [url_descriptor] ASC";
            /* character array delimiter containing only the whitespace character. 
             */
            char[] delimiter = { ' '};
            /* The string that will be replaced based on the selected value of the radio button list rbAndOrNot.
             */
            string OR = "OR", AND = "AND",NOT = "NOT", choice = "";
            /* The string that is used when the case sensitive checkbox in the Cyberminer.aspx is unchecked.
             * i.e no collation string needs to be added to the query.
             */
            string collate = "";
            /*  Conditional if statement to case whether the case sensitive checkbox is check or unchecked. 
             */
            if (cbCaseSensitive.Checked == true) 
            {
                /* Include the Collate statement if checked otherwise the collate string remains empty.
                 */
                collate = " COLLATE Latin1_General_CS_AS ";
            }
            /* Conditional if statements to check which And , Or or Not in selected in the radio 
             * button list rbAndOrNot.
             */
            if (rblAndOrNot.SelectedValue == OR)
            {   /* 
                 * choice is set to the string OR if OR is selected in the radio 
                 * button list rbAndOrNot.
                 */
                choice = OR;
            }
            else if (rblAndOrNot.SelectedValue == AND)
            {
                /* choice is set to the string AND if OR is selected in the radio 
                 * button list rbAndOrNot.
                 */
                choice = AND;
            }
            else if (rblAndOrNot.SelectedValue == NOT)
            {
                /* choice is set to the string NOT if NOT is selected in selected in the radio 
                 * button list rbAndOrNot.
                 */
                choice = NOT;
            }
            /* If the choice made was an AND or OR then the if condition statement execute.
             */
            if (choice == OR || choice == AND)
            {   /* A loop for each sentence in ANCES the statement mentioned within the foreach loop are exceute
                 */
                foreach (String sentence in ANECS)
                {
                    /* split the sentence in to words. Delimiter is the whitespace. 
                     */
                    string[] firstWord = sentence.Split(delimiter);
                    /* add the first word from each sentence and make the search for example '%www%', '%amazon%'
                     * from descriptor "www amazon". 
                     */
                    query += "[url_descriptor]" + collate + " LIKE '% " + firstWord[0] + "'" + choice +" [url_descriptor] "
                        + collate + " LIKE '" + firstWord[0] + " %' " + choice + " [url_descriptor] "
                        + collate + " LIKE '" + firstWord[0] + "' " + choice + " [url_descriptor] " 
                        + collate + " LIKE " + "'% " + firstWord[0];
                    /* add the choice "AND" or "OR" string in between each of the words. For example,
                     * "'%www%' OR '%amazon%'".
                     */
                    if (sentence != ANECS.Last()) { query +=" %' "+ choice + " "; }
                }
                /* add the endQueryString here.
                 */
                query += endQueryString;
            }
            else if (choice == NOT) 
            {
                /* If the choice made was a NOT then the if condition statement execute.
                 */
                query = "SELECT [url_descriptor], [url_hyplerlink], [date_modified]" +
                                   " FROM [url_info] WHERE( ";
                /* A loop for each sentence in ANCES the statement mentioned within the foreach loop are exceute
                 */
                foreach (String sentence in ANECS)
                {
                   
                    /* Split the sentences into words.
                     */
                    string[] firstWord = sentence.Split(delimiter);
                    /* add the first word from each sentence and make the search for example '%www%', '%amazon%'
                     * from descriptor "www amazon". 
                     */
                    /* Add the collate statement to the query string.
                    */

                    query += "[url_descriptor]" + collate + " NOT LIKE '% " + firstWord[0] + "'" + " AND [url_descriptor] "
                        + collate + " NOT LIKE " + "'" + firstWord[0] + " %'" + " AND [url_descriptor] "
                        + collate + " NOT LIKE " + "'" + firstWord[0] + "'" + " AND [url_descriptor]" 
                        + collate + " NOT LIKE '% " + firstWord[0];

                    /* Add the AND keyword. OR was not used here because it would become a regular OR search.
                     */
                    if (sentence != ANECS.Last()) { query += " %' AND "; }
                }
                /* end query string for NOT.
                 */
                query += " %' ) ORDER BY [url_descriptor] ASC";
            }
            /*
             */
            return query;
        }

        /// <summary>
        /// Resets the labels and lists.
        /// </summary>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:52 AM
        private void resetLabelsAndLists()
        {
            /* Empty he contents of the list box lboxSentences
             */
            lblDBError.Text = "";
            lboxSentences.Items.Clear();
            /* Empty he contents of the list box lboxCS
             */
            lboxCS.Items.Clear();
            /* Empty he contents of the list box lboxNECS
             */
            lboxNECS.Items.Clear();
            /* Empty he contents of the list box lboxANECS
             */
            lboxANECS.Items.Clear();
        }

        /// <summary>
        /// Processes the sentences.
        /// </summary>
        /// <returns></returns>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:53 AM
        private List<string> processSentences()
        {   /* Will store the sentences entered.
             */
            List<string> sentences = new List<string>();
            /* The whitespace will be trimmed on the start and the end of the sentences and stored in trimmedSentences
             */
            List<string> trimmedSentences = new List<string>();
            /* Will store the Trimmed Circular Shifted Lines.
             */
            List<string> TCSS = new List<string>();
            /* Will store the Noise eliminated Trimmed Circular Shifted Lines(List 1 NETCSSRS[0]) 
             * and the removed sentence in (List 2 NETCSSRS[1]). 
             */
            List<List<string>> NETCSSRS = new List<List<string>>();
            /* Will store the Trimmed sentences and the original sentences before Nosie Elimination.
             */
            List<string> TCSSOS = new List<string>();
            /* Will stroe the Alphabetized Noise eliminated Trimmed Circular Shifted Lines
             */
            List<string> ANETCSSRS = new List<string>();
            /* Create an object CShift of type CircularShift (Requires the KWIC Namspace).
             */
            CircularShift CShift = new CircularShift();
            /* Create an object NE of type NoiseElimator (Sorry about the typo) (Requires the KWIC Namspace).
             */
            NoiseElimator NE = new NoiseElimator();
            /* Create an object CShift of type CircularShift (Requires the KWIC Namspace).
             */
            Alphabetizer Alpha = new Alphabetizer();

            /* get the sentences from the text box using the txtSearch's Text property.
             */
            sentences = getSentences(txtSearch.Text);
            /* Trim the start and end whitespaces using the trimStartAndEndSpace method.
             */
            trimmedSentences = trimStartAndEndSpace(sentences);

            /* display the trimmedSentences in the listbox.
             */
            displaySentences(trimmedSentences);

            /* Get the circularly shifted lines.
             */
            TCSS = CShift.getCS(trimmedSentences);
            /* Display the circularly shifted lines.
             */
            displayCS(TCSS);

            /* Add the original sentences to the list TCSSOS.
             */
            TCSSOS.AddRange(trimmedSentences);
            /* Add the circularly shifted lines to the list TCSSOS.
             */
            TCSSOS.AddRange(TCSS);
            /* Noise eliminate the sentences in TCSSOS.
             */
            NETCSSRS = NE.getNECS(TCSSOS);
            /* Display the noise elimated circular shifts in the list box
             */
            displayNETCSS(NETCSSRS);
            /* Aplhabetically sort the list NETCSSRS[0] and store it in ANETCSSRS
             */
            ANETCSSRS = Alpha.alphabetize(NETCSSRS[0]);
            /* 
             */
            displayANETCSSRS(ANETCSSRS);
            /* Return the list ANETCSSRS
             */
            return ANETCSSRS;
        }

        /// <summary>
        /// Displays the ANETCSSRS.
        /// </summary>
        /// <param name="ANETCSSRS">The ANETCSSRS.</param>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:55 AM
        private void displayANETCSSRS(List<string> ANETCSSRS)
        {
            /* Add the items in the list ANETCSSRS to the list box lboxANECS
             */
            ANETCSSRS.ForEach(t => lboxANECS.Items.Add(t));
            
        }

        /// <summary>
        /// Displays the NETCSS.
        /// </summary>
        /// <param name="NETCSSRS">The NETCSSRS.</param>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:55 AM
        private void displayNETCSS(List<List<string>> NETCSSRS)
        {
            /* Add the items in the list NETCSSRS[0] to the list box lboxNECS
             */
            NETCSSRS[0].ForEach(t => lboxNECS.Items.Add(t));
            /* Add the items in the list NETCSSRS[1] to the list box lboxRS
             */
            NETCSSRS[1].ForEach(t => lboxRS.Items.Add(t));
        }

        /// <summary>
        /// Displays the CS.
        /// </summary>
        /// <param name="TCSS">The TCSS.</param>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:56 AM
        private void displayCS(List<string> TCSS)
        {
            /* Add the items in the list TCSS to the list box lboxCS
             */
            TCSS.ForEach(t => lboxCS.Items.Add(t)); 
        }

        /// <summary>
        /// Displays the sentences.
        /// </summary>
        /// <param name="trimmedSentences">The trimmed sentences.</param>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:56 AM
        private void displaySentences(List<string> trimmedSentences)
        {
            /* Add the items in the list trimmedSentences to the list box lboxSentences
             */
            trimmedSentences.ForEach(t => lboxSentences.Items.Add(t));
        }

        /// <summary>
        /// Trims the start and end space.
        /// </summary>
        /// <param name="sentences">The sentences.</param>
        /// <returns></returns>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:56 AM
        private List<string> trimStartAndEndSpace(List<string> sentences)
        {
            /* Will store the list of the trimmed Sentences
             */
            List<string> trimmedSentences = new List<string>();

            /* Loop through all the sentences in sentences list. 
             */
            for (int i = 0; i < sentences.Count(); i++)
            {
                /* Trim the white space at the start and end of the sentences and add them to the 
                 * trimmedSentences list.
                 */
                trimmedSentences.Add(sentences[i].TrimStart().TrimEnd());
            }
            /* return the trimmedSentences
             */
            return trimmedSentences; 
        }

        /// <summary>
        /// Gets the sentences.
        /// </summary>
        /// <param name="searchText">The search text.</param>
        /// <returns></returns>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:57 AM
        private List<string> getSentences(string searchText)
        {
            /* Will store the sentences.
             */
            List<string> sentences = new List<string>();
            /* Delimiter of type Character array  containing the '.' period character.
             */
            Char[] delimiter = { '.' };
            /* split the sentences in the searchText by '.' period character convert it to a list and
             * store it in sentences list.
             */
            sentences = searchText.Split(delimiter).ToList();
            /* Removed whitespace between 2 periods, For example "www amazon. . codeplex"
             * here the white space would be add to the list and hence in order to avoid this 
             * the next few step will perform the necessary tasks. 
             */
            List<string> TSList = new List<string>();
            /* get the number of sentences in the list sentences
             */
            int numberOfSentences = sentences.Count();

            /* Loop through all the sentences
             */
            for (int i = 0; i < numberOfSentences; i++)
            {
                /* Trim the sentence in the list and if that is equal to the ""(an empty string) then
                 * dont add it to the new list.
                 */
                if (!(sentences[i].Trim() == ""))
                {
                    TSList.Add(sentences[i]);
                }
            }
            /* Return the list of triimed sentences TSList
             */
            return TSList;
        }

        /// <summary>
        /// Handles the CheckedChanged event of the cbXray control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:57 AM
        protected void cbXray_CheckedChanged(object sender, EventArgs e)
        {
            /* Conditional if statement to check is xray checkbox is checked.
             */
            if (cbXray.Checked == true)
            {
                /* If checked then make the detailsPanel contians the list boxes visible
                 */
                detailsPanel.Visible = true;
            }
            else 
            {
                /* Make them invisible
                     */
                detailsPanel.Visible = false;
            }
        }

        /// <summary>
        /// Changes the page.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="PagePropertiesChangingEventArgs" /> instance containing the event data.</param>
        /// The following was created by mgsurya developed on the machineMGSURYA-PC on 12/4/2012, 5:57 AM
        protected void ChangePage(object sender,PagePropertiesChangingEventArgs e) 
        {
            /* When ever the the DataPager's Page index Changes the ChangePage method is invoked by the list view. 
             * Mentioned as one of the properties of the list view lvSearchResults. The DataPager and lvSearchResults
             * are connected by the DataPager Property ControlID found on the Cyberminer.aspx page
             */
            DataPager.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
            /* get the circurlar shifts.
             */
            ANETCSSRS = processSentences();
            /* search the database
             */
            this.searchDB(ANETCSSRS);

        }
    }
}